﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
//using System.Windows.Forms;
using System.Runtime.InteropServices;
using Roperation;
using texture2d = Microsoft.Xna.Framework.Graphics.Texture2D;
using XnaRect = Microsoft.Xna.Framework.Rectangle;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using KGMedia;
namespace JYoperation.Class
{
    /*
    Public Type RLEPic
    Width As Integer   ' 图片宽度
    Height As Integer  ' 图片高度
    X As Integer       ' 图片x偏移
    Y As Integer       ' 图片y偏移
    datalong As Long   ' 图片RLE压缩数据长度
    data() As Byte     ' 图片RLE压缩数据
    Data32() As Long   ' 图片32位压缩数据
    End Type*/
    public struct JYConfig
    {
        public const int XSCALE = 18;
        public const int YSCALE = 9;

        public const int RxL = -34;
        public const int RxR = 34;
        public const int RYL = -34;
        public const int RYR = 34;

        public const int MMapWidth = 480;
        public const int MMapHeight = 480;
    }
    // D* 事件信息

    public struct D_Event_type
    {
        public short isGo;
        public short id;
        public short EventNum1;
        public short EventNum2;
        public short EventNum3;
        public short picnum1;
        public short picnum2;
        public short picnum3;
        public short PicDelay;
        public short X;
        public short Y;
    }
    public class RlePic
    {
        public short width;
        public short Height;
        public short x;
        public short y;
        public int datalong;
        public byte[] data;
        public Texture2D ConvertToTexture(GraphicsDevice graphicsdevice, RGBtype[,] JYcolor)
        {

                texture2d texture = new texture2d(graphicsdevice, width, Height, false, SurfaceFormat.Color);
                //decode
                uint[] s = new uint[width * Height];
                #region decode
            int i = 0;
            byte PicWidth;
            int piclong, masklong;
            int Px = 0; int Py = 0;
            int dx = Px;

            while (i < datalong)
            {
                PicWidth = data[i];
                i++;
                piclong = PicWidth + i;
                while (i < piclong)
                {
                    Px += data[i++];// i++;
                    masklong = data[i] + i + 1; i++;
                    while (i < masklong)
                    {
                        int pos = Px + Py * width;
                        byte tmpbyte = data[i];
                        s[pos] = JYcolor[0, tmpbyte].ARGB;
                        Px++; i++;
                    }
                }
                Py++; Px = dx;
            }
            #endregion
                texture.SetData(s);
                return texture;
                
            
            
        }
    }
    public class JYpath
    {
        //大地图
        public string FileMmapGRP;
        public string FileMmapIdx;
        //5大金刚
        public string FileEarthData;
        public string FileSurfaceData;
        public string FileBuildingData;
        public string FileBuildxData;
        public string FileBuildyData;
        //云层
        public string FileCloudGRP;
        public string FileCloudIdx;
        //场景
        public string FileSmapGRP;
        public string FileSmapIdx;
        public string FileSindatagrp;
        public string FileDindatagrp;
        public string FileCol;
        //头像
        public string FileHdgrp;
        public string FileHdIdx;
        //画板大小
        public int Width;
        public int Height;
        //title.big
        public string FileTitle;
        //气候
        public string FileWeatherGRP;
        public string FileWeatherIdx;
        //事件
        public string FileKdefgrp;
        public string FileKdefIdx;
        //对话
        public string FileTalkgrp;
        public string FileTalkIdx;
    }
    public struct RGBtype
    {
        public byte bb;
        public byte gg;
        public byte rr;
        public byte aa;
        public uint ARGB;
    }
    public struct M
    {
        public int x;
        public int y;
    }
    /* public struct MMapType
     {
         public short[,] EarthData;//主地图地面贴图编号数据
         public short[,] SurfaceData;// 主地图地面表面贴图编号数据
         public short[,] BuildingData;// 主地图建筑贴图编号数据
         public short[,] BuildxData;// 主地图建筑占用坐标x数据
         public short[,] BuildyData;// 主地图建筑占用坐标y数据
     }*/
    public class JYcore
    {

        abstract public class MapBase
        {
            protected RlePic[] MMapRle = null;//= new List<RlePic>();
            protected RlePic[] SRle = null;//= new List<RlePic>();
            protected RlePic[] CloudRle = null;
            protected RGBtype[,] JYcolor = null;
            protected uint[] s = null;

            protected short walk = 2502;
            protected int RollInt = 0;//时序
            public int NowColIndex = 0;

            /// 读取调色板
            /// </summary>
            /// <param name="filename">文件名称</param>
            /// <returns>返回调色板值</returns>
            protected RGBtype[,] LoadColor(string filename)
            {
                RGBtype[,] m_color_RGB = null;
                using (FileStream fs = new FileStream(filename, FileMode.Open))
                {
                    int colcnt = (int)(fs.Length / (256 * 3));
                    m_color_RGB = new RGBtype[colcnt, 256];
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        for (int k = 0; k < colcnt; k++)
                        {
                            for (int i = 0; i < 256; i++)
                            {
                                RGBtype tmprgb = new RGBtype();
                                tmprgb.bb = (byte)(br.ReadByte() * 4);
                                tmprgb.gg = (byte)(br.ReadByte() * 4);
                                tmprgb.rr = (byte)(br.ReadByte() * 4);
                                tmprgb.aa = 0xff;
                                tmprgb.ARGB = (uint)Color.FromArgb(tmprgb.aa, tmprgb.rr, tmprgb.gg, tmprgb.bb).ToArgb();
                                m_color_RGB[k, i] = tmprgb;
                            }
                        }
                    }
                }
                return m_color_RGB;
            }

            static XnaRect realRect;
            public static XnaRect RealRect
            {
                get { return realRect; }
                set
                {
                    realRect = value;
                    Left = value.Left;
                    Right = value.Right;
                    Bottom = value.Bottom;
                    Top = value.Top;
                }
            }
            public static XnaRect WinRect;
            public static int Left = 0;
            public static int Right = 0;
            public static int Bottom = 0;
            public static int Top = 0;

            protected int centerx = 0, centery = 0;

            /// <summary>
            /// 获取场景坐标
            /// </summary>
            /// <param name="X"></param>
            /// <param name="Y"></param>
            /// <param name="cx"></param>
            /// <param name="cy"></param>
            /// <returns></returns>
            protected M GetXyInScene(int X, int Y, int cx, int cy)
            {
                X++;
                Y++;
                M tmpM = new M();
                tmpM.x = (X - cx) * JYConfig.XSCALE - (Y - cy) * JYConfig.XSCALE + centerx;
                tmpM.y = (X - cx) * JYConfig.YSCALE + (Y - cy) * JYConfig.YSCALE + centery;
                return tmpM;
            }
            /// <summary>
            /// 删除第一幅画
            /// </summary>
            /// <param name="fileId"></param>
            /// <param name="filePic"></param>
            /// <returns></returns>
            protected RlePic[] LoadRlePic(string fileId, string filePic)
            {
                return LoadRlePic(fileId, filePic,true);
            }
            /// <summary>
            /// 读取smap,RLEPIC等等
            /// </summary>
            /// <param name="fileId"></param>
            /// <param name="filePic"></param>
            /// <returns></returns>
            protected RlePic[] LoadRlePic(string fileId, string filePic,bool isSmp)
            {
                long MapPicNum = 0; int[] mappidx;
                List<RlePic> tmpLst = new List<RlePic>();
                using (FileStream fs = new FileStream(fileId, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        MapPicNum = fs.Length / 4;
                        mappidx = new int[MapPicNum];
                        for (int i = 0; i < MapPicNum; i++)
                            mappidx[i] = br.ReadInt32();
                    }
                }
                using (FileStream fs = new FileStream(filePic, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        int piclong = 0;
                        RlePic tmpRle = new RlePic();
                        for (int i = 0; i < MapPicNum; i++)
                        {
                            //offset = mappidx[i];
                            //fs.Seek(offset, SeekOrigin.Begin);
                            if (i == 0)
                                piclong = mappidx[0];
                            else
                                piclong = mappidx[i] - mappidx[i - 1];

                            if (piclong > 0)
                            {
                                tmpRle = new RlePic();
                                //br.ReadByte();
                                tmpRle.width = br.ReadInt16();
                                tmpRle.Height = br.ReadInt16();
                                tmpRle.x = br.ReadInt16();
                                tmpRle.y = br.ReadInt16();
                                tmpRle.datalong = piclong - 8;
                                tmpRle.data = br.ReadBytes(tmpRle.datalong);
                                tmpLst.Add(tmpRle);
                                // br.ReadByte();
                            }
                            else
                            {
                                tmpLst.Add(tmpRle);
                            }
                        }
                        if (isSmp)
                        {
                            //杀掉0号数据
                            tmpRle = new RlePic();
                            //br.ReadByte();
                            tmpRle.width = 0;
                            tmpRle.Height = 0;
                            tmpRle.x = 0;
                            tmpRle.y = 0;
                            tmpRle.datalong = 0;
                            tmpRle.data = new byte[0];
                            tmpLst[0] = tmpRle;
                        }
                    }

                }

                return tmpLst.ToArray();
            }

            /// <summary>
            /// 绘制RLE
            /// </summary>
            /// <param name="pic"></param>
            /// <param name="x"></param>
            /// <param name="y"></param>
            protected void DrawPic(RlePic[] Rle, int Index, int Px, int Py, bool useroll = true)
            {
                if (Index <= 0 || Index > Rle.Length) return;
                RlePic pic = Rle[Index];
                //if ((Px > centerx * 2 || Py > centery * 2 || Px < 0 || Py < 0) && ((Px +pic.width - pic.x)>centerx*2||((Py+pic.Height-pic.y)>centery*2)||((Py+pic.Height-pic.y)<0)||(Px +pic.width - pic.x)<0)) return;
                if (pic.width == 1 && pic.Height == 1) return;

                int i = 0;
                byte PicWidth;
                int piclong, masklong;
                int x = Px - pic.x; int y = Py - pic.y;
                if (x >= centerx * 2)
                    return;
                if (y >= centery * 2)
                    return;
                if (x + pic.width < 0)
                    return;
                if (y + pic.Height < 0)
                    return;
                int dx = x;

                while (i < pic.datalong)
                {
                    PicWidth = pic.data[i];
                    i++;
                    piclong = PicWidth + i;
                    while (i < piclong)
                    {
                        x += pic.data[i++];// i++;
                        masklong = pic.data[i] + i + 1; i++;
                        while (i < masklong)
                        {
                            if (x < Right && y < Bottom && x >= Left && y >= Top)
                            {
                                int pos = x + y * centerx * 2;
                                if ((s[pos] & 0xff000000) == 0)
                                {
                                    byte tmpbyte = pic.data[i];
                                    if (useroll)
                                    {
                                        if (tmpbyte >= 0xe0 && tmpbyte <= 0xe7)
                                        {
                                            tmpbyte -= (byte)(RollInt / 4);
                                            if (tmpbyte < 0xe0)
                                                tmpbyte += 8;
                                        }
                                        else if (tmpbyte >= 0xf4 && tmpbyte <= 0xfc)
                                        {
                                            tmpbyte -= (byte)(RollInt / 4);
                                            if (tmpbyte < 0xf4)
                                                tmpbyte += 8;
                                        }
                                    }
                                    s[pos] = JYcolor[NowColIndex, tmpbyte].ARGB;
                                }
                            }
                            x++; i++;
                        }
                    }
                    y++; x = dx;
                }
            }

            //protected virtual short GetWalk()
            //{
            //    return walk;
            // }
        }
        
        public class Mmapcore : MapBase
        {
            //int cloudx = 0;
            short[, ,] MapData = new short[JYConfig.MMapWidth, JYConfig.MMapHeight, 5];
            short[,] temp = new short[JYConfig.MMapWidth, JYConfig.MMapHeight];
            bool[,] temproll = new bool[JYConfig.MMapWidth, JYConfig.MMapHeight];
            M[] BuildingList = new M[2000];
            M[] CenterList = new M[2000];
            bool[] RollList = new bool[2000];
            int mface = 0;
            //阻挡
            public short[,] MmapMask = new short[JYConfig.MMapWidth, JYConfig.MMapHeight];
            //是否通行
            public short[,] MmapCanwalk = new short[JYConfig.MMapWidth, JYConfig.MMapHeight];
            /// <summary>
            /// 获取行走贴图，目前无用
            /// </summary>
            /// <returns></returns>
            private short GetWalk(int Face)
            {
                //if (Face == 5) return (short)(2502 + 7 * mface);
                short returnwalk;
                if (Face == 10) return (short)(2501 + 7 * mface);
                if (Face == 9) return (short)(2502 + 7 * mface);
                if (Face > 3)
                {
                    //Face -= 4;
                    if (Face == mface + 4)
                    {
                        walk++;
                        if (walk > 2507) walk = (short)(2502);
                        returnwalk = (short)(walk + 7 * Face);
                        //return (short)(walk * 2);
                    }
                    else
                    {
                        mface = Face;
                        returnwalk = (short)(2502 + 7 * Face);
                    }
                }
                if (Face == mface)
                {
                    walk++;
                    if (walk > 2507) walk = (short)(2502);
                    returnwalk = (short)(walk + 7 * Face);
                    //return (short)(walk * 2);
                }
                else
                {
                    mface = Face;
                    returnwalk = (short)(2502 + 7 * Face);
                }
                //return (short)((walk + 7 * Face) * 2);
                //if (walk > 2507) walk = 2502;
                return returnwalk;
            }
            public Mmapcore(JYpath jypath)
            {
                if (JYcolor == null)
                    JYcolor = this.LoadColor(jypath.FileCol);
                MMapRle = this.LoadRlePic(jypath.FileMmapIdx, jypath.FileMmapGRP);
                CloudRle = this.LoadRlePic(jypath.FileCloudIdx, jypath.FileCloudGRP);
                MapData = this.LoadMap(jypath);
                centerx = jypath.Width / 2;
                centery = jypath.Height / 2;


                WinRect = new XnaRect(0, 0, centerx * 2, centery * 2);
                RealRect = WinRect;

                if (s == null)
                    s = new uint[jypath.Width * jypath.Height];
                //drawPic(38, 400, 400);
            }
            public void CheckEntrance(List<Rcore.RdataType> Rtmp)
            {
                for (short k = 0; k < Rtmp[3].Rdata0.Count; k++)
                {
                    //x,y
                    MmapCanwalk[Rtmp[3].Rdata0[k].Rbyte[6].dataInt, Rtmp[3].Rdata0[k].Rbyte[7].dataInt] = k;
                    MmapCanwalk[Rtmp[3].Rdata0[k].Rbyte[8].dataInt, Rtmp[3].Rdata0[k].Rbyte[9].dataInt] = k;
                    MmapMask[Rtmp[3].Rdata0[k].Rbyte[8].dataInt, Rtmp[3].Rdata0[k].Rbyte[9].dataInt] = 0;
                }

            }
            /// <summary>
            /// 绘制RLE
            /// </summary>
            /// <param name="pic"></param>
            /// <param name="x"></param>
            /// <param name="y"></param>
            private void drawCloud(int Index, int Px, int Py, bool useroll = true)
            {
                #region 建议写法
                //DrawPic(CloudRle, Index, Px, Py, useroll);
                #endregion

                #region 建议删除
                if (Index <= 0 || Index > CloudRle.Length) return;
                RlePic pic = CloudRle[Index];
                //if ((Px > centerx * 2 || Py > centery * 2 || Px < 0 || Py < 0) && ((Px +pic.width - pic.x)>centerx*2||((Py+pic.Height-pic.y)>centery*2)||((Py+pic.Height-pic.y)<0)||(Px +pic.width - pic.x)<0)) return;

                int i = 0;
                byte PicWidth;
                int piclong, masklong;
                int x = Px - pic.x; int y = Py - pic.y;
                if (x >= centerx * 2)
                    return;
                if (y >= centery * 2)
                    return;
                if (x + pic.width < 0)
                    return;
                if (y + pic.Height < 0)
                    return;
                int dx = x;

                while (i < pic.datalong)
                {
                    PicWidth = pic.data[i];
                    i++;
                    piclong = PicWidth + i;
                    while (i < piclong)
                    {
                        x += pic.data[i++];// i++;
                        masklong = pic.data[i] + i + 1; i++;
                        while (i < masklong)
                        {
                            if (x < centerx * 2 && y < centery * 2 && x >= 0 && y >= 0)
                            {
                                int pos = x + y * centerx * 2;
                                if ((s[pos] & 0xff000000) == 0)
                                {
                                    byte tmpbyte = pic.data[i];
                                    if (useroll)
                                    {
                                        if (tmpbyte >= 0xe0 && tmpbyte <= 0xe7)
                                        {
                                            tmpbyte -= (byte)(RollInt / 4);
                                            if (tmpbyte < 0xe0)
                                                tmpbyte += 8;
                                        }
                                        else if (tmpbyte >= 0xf4 && tmpbyte <= 0xfc)
                                        {
                                            tmpbyte -= (byte)(RollInt / 4);
                                            if (tmpbyte < 0xf4)
                                                tmpbyte += 8;
                                        }
                                    }
                                    s[pos] = JYcolor[NowColIndex, tmpbyte].ARGB;
                                }
                            }
                            x++; i++;
                        }
                    }
                    y++; x = dx;
                }

                #endregion
            }
            /// <summary>
            /// 读取S文件
            /// </summary>
            /// <param name="filename"></param>
            /// <returns></returns>
            private short[, ,] LoadMap(JYpath jypath)
            {
                short[, ,] sdata = new short[480, 480, 5];
                using (FileStream fs = new FileStream(jypath.FileEarthData, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        for (int j = 0; j < JYConfig.MMapHeight; j++)
                        {
                            for (int i = 0; i < JYConfig.MMapWidth; i++)
                            {
                                sdata[i, j, 0] = br.ReadInt16();
                            }
                        }
                    }
                }
                using (FileStream fs = new FileStream(jypath.FileSurfaceData, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        for (int j = 0; j < JYConfig.MMapHeight; j++)
                        {
                            for (int i = 0; i < JYConfig.MMapWidth; i++)
                            {
                                sdata[i, j, 1] = br.ReadInt16();
                            }
                        }
                    }
                }
                using (FileStream fs = new FileStream(jypath.FileBuildingData, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        for (int j = 0; j < JYConfig.MMapHeight; j++)
                        {
                            for (int i = 0; i < JYConfig.MMapWidth; i++)
                            {
                                sdata[i, j, 2] = br.ReadInt16();
                            }
                        }
                    }
                }
                using (FileStream fs = new FileStream(jypath.FileBuildxData, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        for (int j = 0; j < JYConfig.MMapHeight; j++)
                        {
                            for (int i = 0; i < JYConfig.MMapWidth; i++)
                            {
                                sdata[i, j, 3] = br.ReadInt16();
                            }
                        }
                    }
                }
                using (FileStream fs = new FileStream(jypath.FileBuildyData, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        for (int j = 0; j < JYConfig.MMapHeight; j++)
                        {
                            for (int i = 0; i < JYConfig.MMapWidth; i++)
                            {
                                sdata[i, j, 4] = br.ReadInt16();
                            }
                        }
                    }
                }
                /*
                   if ((earth[x, y] >= 358) and (earth[x, y] <= 362))
    or ((earth[x, y] >= 506) and (earth[x, y] <= 670))
    or ((earth[x, y] >= 1016) and (earth[x, y] <= 1022)) then   
                 * 
                 *  if (earth[x, y] = 838) or ((earth[x, y] >= 612) and (earth[x, y] <= 670)) then
                 */
                for (int j = 0; j < JYConfig.MMapHeight; j++)
                {
                    for (int i = 0; i < JYConfig.MMapWidth; i++)
                    {
                        //   sdata[i, j, 4] = br.ReadInt16();
                        if (sdata[i, j, 2] + sdata[i, j, 3] + sdata[i, j, 4] != 0)
                        {
                            MmapMask[i, j] = 1;
                        }
                        else if (((sdata[i, j, 0] >= 358) && (sdata[i, j, 0] <= 362)) ||
                                    ((sdata[i, j, 0] >= 506) && (sdata[i, j, 0] <= 670)) ||
                                    ((sdata[i, j, 0] >= 1016) && (sdata[i, j, 0] <= 1022)))
                        {
                            MmapMask[i, j] = 2;
                        }
                        else if ((sdata[i, j, 0] == 838) || ((sdata[i, j, 0] >= 612) && (sdata[i, j, 0] <= 670)))
                        {
                            MmapMask[i, j] = 1;
                        }
                        else
                        {
                            MmapMask[i, j] = 0;
                        }
                    }
                }
                return sdata;
            }
            /// <summary>
            /// 绘制场景图，一般来说没有问题
            /// </summary>
            /// <param name="SceneNum"></param>
            /// <param name="X"></param>
            /// <param name="Y"></param>
            /// <returns></returns>
            public uint[] DrawMap(int X, int Y, int face)
            {
                Array.Clear(s, 0, s.Length);
                int k = 0;
                //mapdata[X, Y, 2] = Getwalk();
                for (int i = X + JYConfig.RxR; i >= X + JYConfig.RxL; i--)
                {
                    for (int j = Y + JYConfig.RYR; j >= Y + JYConfig.RYL; j--)
                    {
                        if (i >= 0 && i < 480 && j >= 0 && j < 480)
                        {
                            temp[i, j] = 0;

                            if (MapData[i, j, 2] != 0)
                            {
                                temp[i, j] = MapData[i, j, 2];
                                temproll[i, j] = true;
                            }
                            //                             将主角和空船的位置计入建筑
                            if (i == X && j == Y)
                            {
                                temp[i, j] = (short)(GetWalk(face) * 2);
                                temproll[i, j] = false;
                            }

                            if (temp[i, j] > 0)
                            {
                                BuildingList[k].x = i;
                                BuildingList[k].y = j;

                                RollList[k] = temproll[i, j];
                                int width = MMapRle[temp[i, j] / 2].width;

                                //根据图片的宽度计算图的中点，为避免出现小数，实际是中点坐标的2倍
                                CenterList[k].x = i * 2 - (width + 35) / 36 + 1;
                                CenterList[k].y = j * 2 - (width + 35) / 36 + 1;
                                k = k + 1;
                            }
                        }
                    }
                }

                //按照中点坐标排序
                for (int i = 0; i < k - 1; i++)
                {
                    for (int j = i + 1; j < k; j++)
                    {
                        if (CenterList[i].x + CenterList[i].y > CenterList[j].x + CenterList[j].y)
                        {
                            M pos = BuildingList[i];
                            BuildingList[i] = BuildingList[j];
                            BuildingList[j] = pos;
                            pos = CenterList[i];
                            CenterList[i] = CenterList[j];
                            CenterList[j] = pos;

                            RollList[i] = RollList[i] ^ RollList[j];
                            RollList[j] = RollList[i] ^ RollList[j];
                            RollList[i] = RollList[i] ^ RollList[j];
                        }
                    }
                }
                //for (int i = 0; i < 480; i += 50)
                //{
                //    this.drawCloud(1, i + cloudx, i);
                //}
                //cloudx++;
                for (int i = k - 1; i >= 0; i--)
                {
                    int x = BuildingList[i].x;
                    int y = BuildingList[i].y;
                    M m1 = GetXyInScene(x, y, X, Y);
                    DrawPic(MMapRle, temp[x, y] / 2, m1.x, m1.y, RollList[i]);
                }


                for (int i = X + JYConfig.RxR; i >= X + JYConfig.RxL; i--)
                {
                    for (int j = Y + JYConfig.RYR; j >= Y + JYConfig.RYL; j--)
                    {
                        if (i >= 0 && i < 480 && j >= 0 && j < 480)
                        {
                            M m1 = GetXyInScene(i, j, X, Y);
                            DrawPic(MMapRle, MapData[i, j, 1] / 2, m1.x, m1.y);
                            DrawPic(MMapRle, MapData[i, j, 0] / 2, m1.x, m1.y);
                        }
                    }
                }
                RollInt = (RollInt + 1) % 32;
                return s;
            }
        }
        public class Scenecore : MapBase
        {
            public int mface = 0;
            public short[, , ,] SinData;
            public D_Event_type[,] DefData;
            private int _scenenum = 0;
            public Scenecore(JYpath jypath)
            {
                if (JYcolor == null)
                    JYcolor = this.LoadColor(jypath.FileCol);

                SRle = this.LoadRlePic(jypath.FileSmapIdx, jypath.FileSmapGRP);
                SinData = this.LoadS(jypath.FileSindatagrp);
                DefData = this.LoadD(jypath.FileDindatagrp);
                centerx = jypath.Width / 2;
                centery = jypath.Height / 2;

                WinRect = new XnaRect(0, 0, centerx * 2, centery * 2);
                RealRect = WinRect;
                if (s == null)
                    s = new uint[jypath.Width * jypath.Height];
                //drawPic(38, 400, 400);
            }
            /// <summary>
            /// 获取行走贴图，目前无用
            /// </summary>
            /// <returns></returns>
            private short GetWalk(int Face)
            {
                //if (Face == 5) return (short)(2502 + 7 * mface);
                short returnwalk;
                if (Face == 10) return (short)(2501 + 7 * mface);
                if (Face == 9) return (short)(2502 + 7 * mface);
                if (Face == mface)
                {
                    walk++;
                    if (walk > 2507) walk = (short)(2502);
                    returnwalk = (short)(walk + 7 * Face);
                    //return (short)(walk * 2);
                }
                else
                {
                    mface = Face;
                    returnwalk = (short)(2502 + 7 * Face);
                }
                //return (short)((walk + 7 * Face) * 2);
                //if (walk > 2507) walk = 2502;
                return returnwalk;
            }
            /// <summary>
            /// 读取D文件
            /// </summary>
            /// <param name="filename"></param>
            /// <returns></returns>
            private D_Event_type[,] LoadD(string filename)
            {
                D_Event_type[,] ddata = new D_Event_type[_scenenum, 200];
                using (FileStream fs = new FileStream(filename, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        for (int l = 0; l < _scenenum; l++)
                        {
                            for (int k = 0; k < 200; k++)
                            {
                                //读取D数据
                                ddata[l, k].isGo = br.ReadInt16();
                                ddata[l, k].id = br.ReadInt16();
                                ddata[l, k].EventNum1 = br.ReadInt16();
                                ddata[l, k].EventNum2 = br.ReadInt16();
                                ddata[l, k].EventNum3 = br.ReadInt16();
                                ddata[l, k].picnum1 = br.ReadInt16();
                                ddata[l, k].picnum2 = br.ReadInt16();
                                ddata[l, k].picnum3 = br.ReadInt16();
                                ddata[l, k].PicDelay = br.ReadInt16();
                                ddata[l, k].X = br.ReadInt16();
                                ddata[l, k].Y = br.ReadInt16();
                            }
                        }
                    }
                }
                return ddata;
            }
            //private short
            /// <summary>
            /// 读取S文件
            /// </summary>
            /// <param name="filename"></param>
            /// <returns></returns>
            private short[, , ,] LoadS(string filename)
            {
                short[, , ,] sdata = new short[64, 64, 6, 200];
                using (FileStream fs = new FileStream(filename, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        int scenenum = (int)fs.Length / (64 * 64 * 6 * 2);
                        _scenenum = scenenum;
                        for (int l = 0; l < scenenum; l++)
                        {
                            for (int k = 0; k < 6; k++)
                            {
                                for (int j = 0; j < 64; j++)
                                {
                                    for (int i = 0; i < 64; i++)
                                    {
                                        sdata[i, j, k, l] = br.ReadInt16();
                                    }
                                }
                            }
                        }
                    }
                }
                return sdata;
            }
            /// <summary>
            /// 绘制场景图，一般来说没有问题
            /// </summary>
            /// <param name="SceneNum"></param>
            /// <param name="X"></param>
            /// <param name="Y"></param>
            /// <returns></returns>
            public uint[] DrawScene(int SceneNum, int X, int Y, int Face)
            {
                if (SceneNum < 0) return s;
                Array.Clear(s, 0, s.Length);
                short tmpsindata = SinData[X, Y, 1, SceneNum];
                SinData[X, Y, 1, SceneNum] = (short)(GetWalk(Face) * 2);
                for (int i = X + JYConfig.RxR; i >= X + JYConfig.RxL; i--)
                {
                    for (int j = Y + JYConfig.RYR; j >= Y + JYConfig.RYL; j--)
                    {
                        if (i >= 0 && i < 64 && j >= 0 && j < 64)
                        {
                            M m1 = GetXyInScene(i, j, X, Y);
                            if (SinData[i, j, 3, SceneNum] >= 0)
                            {
                                DrawPic(SRle, DefData[SceneNum, SinData[i, j, 3, SceneNum]].picnum1 / 2,
                                    m1.x, m1.y - SinData[i, j, 4, SceneNum], false);
                            }
                            //空中
                            DrawPic(SRle, SinData[i, j, 2, SceneNum] / 2, m1.x, m1.y - SinData[i, j, 5, SceneNum] - SinData[i, j, 4, SceneNum], false);
                            //建筑

                            DrawPic(SRle, SinData[i, j, 1, SceneNum] / 2, m1.x, m1.y - SinData[i, j, 4, SceneNum], false);
                            //地面
                            DrawPic(SRle, SinData[i, j, 0, SceneNum] / 2, m1.x, m1.y, false);
                        }
                    }
                }
                SinData[X, Y, 1, SceneNum] = tmpsindata;
                return s;
            }
            public bool CanWalk(int X, int Y, int NUM)
            {

                if (SinData[X, Y, 3, NUM] >= 0)
                {
                    if (DefData[NUM, SinData[X, Y, 3, NUM]].isGo == 1)
                        return false;
                    else
                        return true;
                }
                else
                {
                    if (SinData[X, Y, 1, NUM] == 0)
                        return true;
                    else
                        return false;
                }
                //return false;
            }

        }
        //复古，读取big文件
        public class BigCore : MapBase
        {
            RGBtype[,] endcol;
            uint[,] smap;
            int _num;
            int _width, _height;
            public BigCore(JYpath jypath, int width, int height)
            {
                endcol = this.LoadColor(jypath.FileCol);
                _width = width; _height = height;
                smap = drawbigcore(jypath.FileTitle);
            }
            private uint[,] drawbigcore(string filename)
            {
                uint[,] tmpCollection;
                using (FileStream fs = new FileStream(filename, FileMode.Open))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        int bignum = (int)fs.Length / (_width * _height);
                        tmpCollection = new uint[bignum, _width * _height];
                        _num = bignum;
                        for (int i = 0; i < bignum; i++)
                        {
                            for (int j = 0; j < _width * _height; j++)
                            {
                                tmpCollection[i, j] = endcol[NowColIndex, br.ReadByte()].ARGB;
                            }
                        }
                    }
                }
                return tmpCollection;
            }
            public uint[] drawBig(int num)
            {
                if (num < _num)
                {
                    uint[] tmpbig = new uint[_width * _height];
                    for (int i = 0; i < _width * _height; i++)
                    {
                        tmpbig[i] = smap[num, i];
                    }
                    return tmpbig;
                }
                else
                {
                    return null;
                }
            }
        }

        public class textureCore:MapBase
        {
            public texture2d[] GetAllTexture(string ColPath,string fileId, string filePic, GraphicsDevice graphics)
            {
                RGBtype[,] endcol = LoadColor(ColPath);
                List<texture2d> tmpLstText = new List<texture2d>();
                RlePic[] tmpLstRle = LoadRlePic(fileId, filePic,false);
                foreach (RlePic tmpRle in tmpLstRle)
                {
                    texture2d tmp2d = tmpRle.ConvertToTexture(graphics, endcol);
                    tmpLstText.Add(tmp2d);
                }
                return tmpLstText.ToArray();
            }
        }
        public class Weather : MapBase
        {
            public Texture2D FogTex = null;
            public Texture2D RectTex = null;

            public List<FogDef> FogList = new List<FogDef>();
            public List<RainDef> RainList = new List<RainDef>();
            public List<SnowDef> SnowList = new List<SnowDef>();

            protected SoundEffectInstance RainSound = null;
            protected SoundEffect RainSoundEft = null;

            protected SoundEffectInstance SnowSound = null;
            protected SoundEffect SnowSoundEft = null;

            public Weather(JYpath jypath, GraphicsDevice gd)
            {
                if (JYcolor == null)
                    JYcolor = this.LoadColor(jypath.FileCol);

                SRle = this.LoadRlePic(jypath.FileWeatherIdx, jypath.FileWeatherGRP);
                FogTex = SRle[1].ConvertToTexture(gd, JYcolor);
                RectTex = SRle[2].ConvertToTexture(gd, JYcolor);


                //                 using (FileStream fs = new FileStream("e:\\1.png", FileMode.Create))
                //                     SnowTex.SaveAsPng(fs, SnowTex.Width, SnowTex.Height);
                //                 using (FileStream fs = new FileStream("e:\\2.png", FileMode.Create))
                //                     FogTex.SaveAsPng(fs, FogTex.Width, FogTex.Height);
            }

            public void NewFog(int count, int screenW, int screenH)
            {
                FogList.Clear();
                for (int i = 0; i < count; i++)
                    FogList.Add(new FogDef(FogTex, screenW, screenH));
            }
            public void NewSnow(int count, int screenW, int screenH)
            {
                SnowList.Clear();
                for (int i = 0; i < count; i++)
                    SnowList.Add(new SnowDef(RectTex, screenW, screenH));
            }
            public void NewRain(int count, int screenW, int screenH)
            {
                RainList.Clear();
                for (int i = 0; i < count; i++)
                    RainList.Add(new RainDef(RectTex, screenW, screenH));

                if (RainSoundEft == null && RainSound == null)
                {
                    RainSoundEft = @".\data\Rain.wav".ToSoundEffect();
                    RainSound = RainSoundEft.CreateInstance();
                    RainSound.IsLooped = true;
                }
            }
            bool _rainEnable = false;
            public bool RainEnable
            {
                get { return _rainEnable; }
                set
                {
                    if (_rainEnable != value)
                    {
                        if (value)
                        {
                            if (RainSound.State != SoundState.Playing)
                                RainSound.Play();
                        }
                        else
                        {
                            if (RainSound.State != SoundState.Stopped)
                                RainSound.Stop();
                        }
                        _rainEnable = value;
                    }
                }
            }
        }

    }

    public class WeatherDef
    {
        public Point Pos = new Point();
        public int Width;
        public int Height;
        public int Speed = 1;
        public Texture2D Pic = null;
        protected Rectangle ScreenRect;
        public float Alpha = 1;

        public WeatherDef(Texture2D pic, int screenW, int screenH)
        {
            Pic = pic;
            ScreenRect = new Rectangle(0, 0, screenW, screenH);
            Reset(false);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="leftscreen">是否从屏幕左端开始</param>
        public virtual void Reset(bool leftscreen = true)
        {
        }
        public virtual void Update()
        {
        }
    }

    public class RainDef : WeatherDef
    {
        //static KGSong rain = new KGSong("rain", @".\audio\Rain.mp3"); 
        public RainDef(Texture2D pic, int screenW, int screenH)
            : base(pic, screenW, screenH)
        {
        }

        public override void Update()
        { 
            Pos = new Point(Pos.X + 1, Pos.Y + Speed);

            if (Pos.X >= ScreenRect.Width)
                Pos.X -= ScreenRect.Width;

            if (Pos.Y >= ScreenRect.Height)
                Pos.Y -= ScreenRect.Height;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="leftscreen">是否从屏幕左端开始</param>
        public override void Reset(bool leftscreen = true)
        {
            Width = 1;
            Height = (KGRandom.Ramdom(20)) + 5;
            Pos = new Point(KGRandom.Ramdom(ScreenRect.Width), KGRandom.Ramdom(ScreenRect.Height));

            Alpha = 0.2f;
            Speed = KGRandom.Ramdom(5) + 10;
        }
    }


    public class SnowDef : WeatherDef
    {
        public SnowDef(Texture2D pic, int screenW, int screenH)
            : base(pic, screenW, screenH)
        {
        }

        public override void Update()
        {
            Pos = new Point(Pos.X + 1 + Speed % 2, Pos.Y + 2 + Speed % 3);

            if (Pos.X >= ScreenRect.Width)
                Pos.X -= ScreenRect.Width;

            if (Pos.Y >= ScreenRect.Height)
                Pos.Y -= ScreenRect.Height;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="leftscreen">是否从屏幕左端开始</param>
        public override void Reset(bool leftscreen = true)
        {
            int size = KGRandom.Ramdom(3) + 1;
            Width = size;
            Height = size;
            Pos = new Point(KGRandom.Ramdom(ScreenRect.Width), KGRandom.Ramdom(ScreenRect.Height));

            Alpha = 0.8f;
            Speed = KGRandom.Ramdom(5000);
        }
    }
    public class FogDef : WeatherDef
    {
        public FogDef(Texture2D pic, int screenW, int screenH)
            : base(pic, screenW, screenH)
        {
        }

        public override void Update()
        {
            Pos = new Point(Pos.X + Speed, Pos.Y);

            if (Pos.X > ScreenRect.Width)
                Reset();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="leftscreen">是否从屏幕左端开始</param>
        public override void Reset(bool leftscreen = true)
        {
            Width = (100 + KGRandom.Ramdom(150)) * Pic.Width / 100;
            Height = (100 + KGRandom.Ramdom(100)) * Pic.Height / 100;

            if (leftscreen)
                Pos = new Point(-Width, (KGRandom.Ramdom(130) - 30) * ScreenRect.Height / 100);
            else
                Pos = new Point((KGRandom.Ramdom(130) - 30) * ScreenRect.Width / 100, (KGRandom.Ramdom(130) - 30) * ScreenRect.Height / 100);

            Alpha = (float)(KGRandom.Ramdom(20) + 20) / 100f;
            Speed = KGRandom.Ramdom(5) + 2;
        }
    }

    static public class KGRandom
    {
        static public int Ramdom(int i)
        {
            if (i <= 0)
                return 0;

            Random ran = new Random(Guid.NewGuid().GetHashCode());
            return ran.Next(0, i);
        }
    }
    static public class ThunderMgr
    {
        static bool Flag = false;
        static SoundEffect thunder1 = @".\data\Thunder1.wav".ToSoundEffect();
        static SoundEffect thunder2 = @".\data\Thunder2.wav".ToSoundEffect();
        static SoundEffectInstance NowWav = null;
        static public float Update(bool Enable = true)
        {
            if (Enable)
            {
                if (KGRandom.Ramdom(60) == (Flag ? 0 : 1))
                {
                    if (NowWav == null || NowWav.State == SoundState.Stopped)
                    {
                        if (NowWav != null)
                        {
                            NowWav.Dispose();
                            NowWav = null;
                        }
                        NowWav = (KGRandom.Ramdom(5) == 0 ? thunder1 : thunder2).CreateInstance();
                        NowWav.Play();
                    }
                    Flag = !Flag;

                    //亮度有个随机看起来比较牛叉
                    return 1.2f + (float)KGRandom.Ramdom(5) / 10;
                }
                else
                    return 0.6f;
            }
            else
                return 1;
        }
    }

    static public class JYExpand
    { 
        public static SoundEffect ToSoundEffect(this string filename)
        {
            if (!File.Exists(filename))
                return null;

            SoundEffect ret = null;
            using (FileStream fs = new FileStream(filename, FileMode.Open))
                ret = SoundEffect.FromStream(fs);

            return ret;
        }

        static public XnaRect SetZoom(this XnaRect p, float Zoom)
        {
            if (Zoom == 1)
                return p;
            XnaRect pt = new XnaRect(
                (int)(p.Width - (p.Width / Zoom)) / 2,
                (int)(p.Height - (p.Height / Zoom)) / 2,
                (int)(p.Width / Zoom),
                (int)(p.Height / Zoom));
            return pt;
        }
    }
}